package se.webbzon.boltzmann.game.object.trigger;

import java.nio.ByteBuffer;

import se.webbzon.boltzmann.debug.Debug;
import se.webbzon.boltzmann.environment.AbstractEnvironment;
import se.webbzon.boltzmann.game.sequence.builder.SequenceBuilder;
import se.webbzon.boltzmann.game.sequence.builder.SequenceBuilderDeflation;
import se.webbzon.boltzmann.game.sequence.builder.SequenceBuilderException;
import se.webbzon.boltzmann.game.sequence.builder.SequenceRowInflatorGroup;
import se.webbzon.boltzmann.object.unknown.Unknown;
import se.webbzon.oschi01.friendly.Friendly;
import se.webbzon.oschi01.worldobject.WorldObject;

public class SequenceTriggerDeflation extends AbstractTriggerDeflation {
	
	private boolean blocking;
	
	private byte[] data;
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new empty trigger deflation. **/
	public SequenceTriggerDeflation(int deflationProperties,
							WorldObject[] dependencies) {
		super(deflationProperties, dependencies);
	}
	
	/** Creates a new trigger deflation from an existing trigger. **/
	public SequenceTriggerDeflation(int deflationProperties,
							SequenceTrigger trigger,
							SequenceBuilderDeflation builderDeflation) {
		super(	deflationProperties, builderDeflation.getDependencies(), 
				trigger);
		data = builderDeflation.getData();
		blocking = trigger.isBlocking();
	}
	
	/*============================================================
	Public Methods
	============================================================*/

	@Override public void inflate(ByteBuffer buff) {
		super.inflate(buff);
		
		// Read from buffer
		blocking = buff.get() != 0;
		data = new byte[buff.getInt()];
		buff.get(data, 0, data.length);
	}

	@Override public ByteBuffer deflate(int allocate) {
		ByteBuffer buff = super.deflate(allocate + 5 + data.length);
		
		// Write to buffer
		buff.put(blocking ? (byte) 1 : (byte) 0);
		buff.putInt(data.length);
		buff.put(data);
		
		return buff;
	}
	
	/*============================================================
	Friendly Methods
	============================================================*/
	
	/** Creates a new trigger from this trigger defaltion. **/
	@Friendly WorldObject makeTrigger(	AbstractEnvironment env,
										SequenceRowInflatorGroup inflatorGroup) {
		// Extract dependencies for sequence builder
		int dependencies = dependencies();
		WorldObject[] dependencyArray = 
				new WorldObject[dependencies];

		for (int i = 0; i < dependencies; i++)
			dependencyArray[i] = (WorldObject) getDependency(i);

		// Inflate sequence builder
		SequenceBuilderDeflation deflation = 
				new SequenceBuilderDeflation(data,dependencyArray);
		SequenceBuilder builder = null;
		try {
			builder = deflation.inflate(env,inflatorGroup);
		} catch (SequenceBuilderException e) {
			// Return new unknown if an error occurred
			Debug.report(e);
			return new Unknown();
		}
		
		return new SequenceTrigger(env,getCondition(),builder,blocking);
	}
	
}
